package com.ppt;

import com.ppt.model.NumVo;
import com.ppt.model.PptData;
import com.ppt.pptutil.PPTUtil;
import org.apache.poi.sl.usermodel.TableCell;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.xslf.usermodel.*;

import java.awt.*;
import java.io.OutputStream;
import java.text.NumberFormat;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.Collections.singletonList;

/**
 * @author Jack
 */
public class PptDataConverter {

	private final PptData data;

	private final PPTUtil pptUtil;

	public PptDataConverter(PptData data, String tepmlatePath) {
		this.data = data;
		pptUtil = new PPTUtil(tepmlatePath);
	}

	public void outputToFile(String filePath) {
		render();
		pptUtil.writePPT(filePath);
	}

	public void outputToStream(OutputStream os) {
		render();
		pptUtil.writePPT(os);
	}

	private void render() {
		renderTexts();
		renderTables();
		renderCharts();
	}

	private void renderTables() {
		renderTable5_1();//家庭成员信息表(4)
		renderTable6_1();//资产负债表(5)
		renderTable7_1();//收入支出表(7)
		renderTable8_1();//财务分析与诊断(8)
		renderTable12_1();//家庭风险保障现状(12)
		renderTable17_1();//配置建议[现阶段家庭重疾险保障需求](17)
		renderTable18_1();//配置建议[资产调整建议](18)
		renderTable18_2();//配置建议[年结余规划](18)
		renderTable19_20();//配置建议[年化收益](19-20)
		renderTable21_22();//配置建议[年化收益]
		renderTable24();//配置建议[资产配置后前后变化]
	}

	private void renderTexts() {
		renderTextOnPage1();//首页(0)
		renderTextOnPage4();//致函(4)
		renderTextOnPage5();//家庭财务需求/家庭现状(5)
		renderTextOnPage9();//财务比率分析[流动性比率/负债比率](9)
		renderTextOnPage10();//财务比率分析[清偿比率/结余比率/投资比率](10)
		renderTextOnPage11();//财务比率分析[负债收入比率/被动收入比率/小结](11)
		renderTextOnPage12();//家庭风险保障分析[分析结果2](12)
		renderTextOnPage13();//家庭风险保障分析[分析结果3/分析结果4/小结](13)
		renderTextOnPage14();//资产结构及收支结构分析[分析结果1](14)
		renderTextOnPage15();//资产结构及收支结构分析[分析结果2/小结](15)
		renderTextOnPage16();//配置建议[建议1/建议2](16)
		renderTextOnPage17();//配置建议[建议3](17)
		renderTextOnPage18();//配置建议[建议4](18)
		renderTextOnPage19();//配置建议[表格描述3]
		renderTextOnPage20();//配置建议[表格描述4]
		renderTextOnPage21();//配置建议[表格描述5]
		renderTextOnPage22();//配置建议[表格描述6]
		renderTextOnPage25();//最后日期
	}

	private void renderCharts() {
		renderChart6_1();//资产结构图(6)
		renderChart7_1();//收入结构图(7)
		renderChart7_2();//支出结构图(7)
		renderChart8_1();//资产配置布局(8)
		renderChart9_1();//流动性比率(9)
		renderChart9_2();//负债比率(9)
		renderChart10_1();//结余比率(10)
		renderChart10_2();//投资比率(10)
		renderChart11_1();//负债收入比率(11)
		renderChart11_2();//被动收入比率(11)
		renderChart24_1();//资产配置前后变化
	}

	private void renderTextOnPage1() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(0));
		pptUtil.replaceTagInParagraph(textParagraphs.get(0), newMaps("name", data.getName()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(4), newMaps("times", data.getTime()));
	}

	private void renderTextOnPage4() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(3));
		pptUtil.replaceTagInParagraph(textParagraphs.get(0), newMaps("name", "张先生"));
		pptUtil.replaceTagInParagraph(textParagraphs.get(7), newMaps("times", data.getTime()));
	}

	private void renderTextOnPage5() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(4));
		StringBuilder sql = new StringBuilder();
		for (int i = 0; i < data.getRequirements().size(); i++) {
			sql.append(i + 1).append("、").append(data.getRequirements().get(i));
			if (i < data.getRequirements().size() - 1) {
				sql.append("；");
			} else {
				sql.append("。");
			}
			sql.append("\r");
		}
		pptUtil.replaceTagInParagraph(textParagraphs.get(2), newMaps("requirements", sql.toString()));
	}

	private void renderTextOnPage9() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(8));
		pptUtil.replaceTagInParagraph(textParagraphs.get(5), newMaps("liquidityRatio", data.getLiquidityRatio()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(12), newMaps("debtRatio", data.getDebtRatio()));
	}

	private void renderTextOnPage10() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(9));
		pptUtil.replaceTagInParagraph(textParagraphs.get(2), newMaps("debtServiceRatio", data.getDebtServiceRatio()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(4), newMaps("balanceRatio", data.getBalanceRatio()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(13), newMaps("investmentRatio", data.getInvestmentRatio()));
	}

	private void renderTextOnPage11() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(10));
		pptUtil.replaceTagInParagraph(textParagraphs.get(2), newMaps("debtToIncomeRatio", data.getDebtToIncomeRatio()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(11),
				newMaps("passiveIncomeRatio", data.getPassiveIncomeRatio()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(20),
				newMaps("summaryOfAnalysis", data.getSummaryOfAnalysis()));
	}

	private void renderTextOnPage12() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(11));
		pptUtil.replaceTagInParagraph(textParagraphs.get(18),
				newMaps("riskAnalysisTitle_2", data.getRiskAnalysisTitle_2()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(19),
				newMaps("riskAnalysisContent_2", data.getRiskAnalysisContent_2()));
	}

	private void renderTextOnPage13() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(12));
		pptUtil.replaceTagInParagraph(textParagraphs.get(1),
				newMaps("riskAnalysisTitle_3", data.getRiskAnalysisTitle_3()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(2),
				newMaps("riskAnalysisContent_3", data.getRiskAnalysisContent_3()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(3),
				newMaps("riskAnalysisTitle_4", data.getRiskAnalysisTitle_4()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(4),
				newMaps("riskAnalysisContent_4", data.getRiskAnalysisContent_4()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(5), newMaps("riskAnalysisTitle_5", " "));
		pptUtil.replaceTagInParagraph(textParagraphs.get(6), newMaps("riskAnalysisContent_5", " "));
		pptUtil.replaceTagInParagraph(textParagraphs.get(8),
				newMaps("summaryOfRiskAnalysis", data.getSummaryOfRiskAnalysis()));
	}

	private void renderTextOnPage14() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(13));
		pptUtil.replaceTagInParagraph(textParagraphs.get(2),
				newMaps("structureAnalysisTitle_1", data.getStructureAnalysisTitle_1()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(3),
				newMaps("structureAnalysisContent_1", data.getStructureAnalysisContent_1()));
	}

	private void renderTextOnPage15() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(14));
		pptUtil.replaceTagInParagraph(textParagraphs.get(1),
				newMaps("structureAnalysisTitle_2", data.getStructureAnalysisTitle_2()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(2),
				newMaps("structureAnalysisContent_2", data.getStructureAnalysisContent_2()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(4),
				newMaps("summaryOfStructureAnalysis", data.getSummaryOfStructureAnalysis()));
	}

	private void renderTextOnPage16() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(15));
		pptUtil.replaceTagInParagraph(textParagraphs.get(2),
				newMaps("suggestionsTitle_1", data.getSuggestionsTitle_1()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(3),
				newMaps("suggestionsContent_1", data.getSuggestionsContent_1()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(4),
				newMaps("suggestionsTitle_2", data.getSuggestionsTitle_2()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(5),
				newMaps("suggestionsContent_2", data.getSuggestionsContent_2()));
	}

	private void renderTextOnPage17() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(16));
		pptUtil.replaceTagInParagraph(textParagraphs.get(8),
				newMaps("suggestionsTitle_3", data.getSuggestionsTitle_3()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(9),
				newMaps("suggestionsContent_3", data.getSuggestionsContent_3()));
	}

	private void renderTextOnPage18() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(17));
		pptUtil.replaceTagInParagraph(textParagraphs.get(1),
				newMaps("suggestionsTitle_4", data.getSuggestionsTitle_4()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(2),
				newMaps("suggestionsTableDesc_1", data.getSuggestionsTableDesc_1()));
		pptUtil.replaceTagInParagraph(textParagraphs.get(16),
				newMaps("suggestionsTableDesc_2", data.getSuggestionsTableDesc_2()));
	}

	private void renderTextOnPage19() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(18));
		pptUtil.replaceTagInParagraph(textParagraphs.get(1),
				newMaps("suggestionsTableDesc_3", data.getSuggestionsTableDesc_3()));
	}

	private void renderTextOnPage20() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(19));
		pptUtil.replaceTagInParagraph(textParagraphs.get(5),
				newMaps("suggestionsTableDesc_4", data.getSuggestionsTableDesc_4()));
	}

	private void renderTextOnPage21() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(20));
		pptUtil.replaceTagInParagraph(textParagraphs.get(2),
				newMaps("suggestionsTableDesc_5", data.getSuggestionsTableDesc_5()));
	}

	private void renderTextOnPage22() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(21));
		pptUtil.replaceTagInParagraph(textParagraphs.get(2),
				newMaps("suggestionsTableDesc_6", data.getSuggestionsTableDesc_6()));
	}

	private void renderTextOnPage25() {
		List<XSLFTextParagraph> textParagraphs = pptUtil.getParagraphsFromSlide(pptUtil.getSlides().get(24));
		pptUtil.replaceTagInParagraph(textParagraphs.get(11), newMaps("times", data.getTime()));
	}

	private void renderTable5_1() {
		List<XSLFTable> tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(4));
		appendRow(tables.get(0), 10, 15, data.getFamilyMembers());
	}

	private void renderTable6_1() {
		List<List<String>> values;
		List<XSLFTable> tables;
		tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(5));
		values = new ArrayList<>();
		String lastCategory = data.getPropertys().size() > 0 ? data.getPropertys().get(0).getCategory() : "";
		List<Integer> rowSpans = new ArrayList<>();
		for (int i = 0; i < data.getPropertys().size(); i++) {
			NumVo property = data.getPropertys().get(i);
			NumVo debt;
			if (i < data.getDebts().size()) {
				debt = data.getDebts().get(i);
			} else {
				debt = new NumVo("", null);
			}
			values.add(
					Arrays.asList(property.getCategory(), property.getName(), fmt(property.getValue()), debt.getName(),
							debt.getValue() == null ? "" : fmt(debt.getValue())));
			if (!Objects.equals(lastCategory, property.getCategory())) {
				rowSpans.add(i);
			}
			lastCategory = property.getCategory();
		}
		final XSLFTable table = tables.get(0);
		appendRow(table, 10, 2, values);
		int lastIndex = 1;
		for (int lastRows : rowSpans) {
			if (lastRows - lastIndex > 0) {
				table.mergeCells(lastIndex, lastRows, 0, 0);
				pptUtil.getTableRows(table).get(lastIndex).getCells().get(0).setTopInset((10 * 2));
			}
			lastIndex = lastRows + 1;
		}
		double totaPpropertys = data.getPropertys().stream().mapToDouble(NumVo::getValue)
				.sum(), totlalDebts = data.getDebts().stream().mapToDouble(NumVo::getValue).sum();
		XSLFTableRow row = table.addRow();
		createBoldCell(row.addCell(), 12, "资产总计", 2);
		createBoldCell(row.addCell(), 12, "", 2);
		createBoldCell(row.addCell(), 12, fmt(totaPpropertys), 2);
		createBoldCell(row.addCell(), 12, "负债合计", 2);
		createBoldCell(row.addCell(), 12, fmt(totlalDebts), 2);
		row.mergeCells(0, 1);
		row = table.addRow();
		createBoldCell(row.addCell(), 12, "净资产", 2);
		createBoldCell(row.addCell(), 12, "", 2);
		createBoldCell(row.addCell(), 12, fmt(totaPpropertys - totlalDebts), 2);
		createBoldCell(row.addCell(), 12, "", 2);
		createBoldCell(row.addCell(), 12, "", 2);
		row.mergeCells(0, 1);
		row.mergeCells(2, 4);
		row.getCells().forEach(c -> pptUtil.setCellFillColor(c, "#CFB478"));
	}

	private void renderTable7_1() {
		List<XSLFTable> tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(6));
		List<List<String>> values = new ArrayList<>();
		String lastCategory = data.getIncomes().size() > 0 ? data.getIncomes().get(0).getCategory() : "";
		List<Integer> rowSpans = new ArrayList<>();
		for (int i = 0; i < data.getIncomes().size(); i++) {
			NumVo property = data.getIncomes().get(i);
			NumVo debt;
			if (i < data.getExpands().size()) {
				debt = data.getExpands().get(i);
			} else {
				debt = new NumVo("", null);
			}
			values.add(
					Arrays.asList(property.getCategory(), property.getName(), fmt(property.getValue()), debt.getName(),
							debt.getValue() == null ? "" : fmt(debt.getValue())));
			if (!Objects.equals(lastCategory, property.getCategory())) {
				rowSpans.add(i);
			}
			lastCategory = property.getCategory();
		}
		final XSLFTable table = tables.get(0);
		appendRow(table, 10, 2, values);
		int lastIndex = 1;
		for (int lastRows : rowSpans) {
			if (lastRows - lastIndex > 0) {
				table.mergeCells(lastIndex, lastRows, 0, 0);
				pptUtil.getTableRows(table).get(lastIndex).getCells().get(0).setTopInset((10 * 2));
			}
			lastIndex = lastRows + 1;
		}
		double totalIncome = data.getIncomes().stream().mapToDouble(NumVo::getValue)
				.sum(), totalExpand = data.getExpands().stream().mapToDouble(NumVo::getValue).sum();
		XSLFTableRow row = table.addRow();
		createBoldCell(row.addCell(), 12, "收入合计", 2);
		createBoldCell(row.addCell(), 12, "", 2);
		createBoldCell(row.addCell(), 12, fmt(totalIncome), 2);
		createBoldCell(row.addCell(), 12, "支出合计", 2);
		createBoldCell(row.addCell(), 12, fmt(totalExpand), 2);
		row.mergeCells(0, 1);
		row = table.addRow();
		createBoldCell(row.addCell(), 12, "年度结余", 2);
		createBoldCell(row.addCell(), 12, "", 2);
		createBoldCell(row.addCell(), 12, fmt(totalIncome - totalExpand), 2);
		createBoldCell(row.addCell(), 12, "", 2);
		createBoldCell(row.addCell(), 12, "", 2);
		row.mergeCells(0, 1);
		row.mergeCells(2, 4);
		row.getCells().forEach(c -> pptUtil.setCellFillColor(c, "#CFB478"));
	}

	private void renderTable8_1() {
		List<XSLFTable> tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(7));
		XSLFTable table = tables.get(0);
		List<XSLFTableRow> rows = table.getRows();
		for (int i = 1; i < rows.size(); i++) {
			if (i - 1 < data.getFinancialAnalysis().size()) {
				XSLFTableCell cell = rows.get(i).getCells().get(3);
				XSLFTextParagraph textParagraph = pptUtil.addCellParagraph(cell);
				pptUtil.addParagraphText(textParagraph, true, data.getFinancialAnalysis().get(i - 1) + "%");
				pptUtil.setCellHorizontalAlign(cell, "center");
				pptUtil.setCellVerticalAlign(cell, "center");
				cell.setTopInset(5);
				cell.setBottomInset(15);
			}
		}
	}

	private void renderTable12_1() {
		List<XSLFTable> tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(11));
		appendRow(tables.get(0), 8, 5, data.getFamilyRiskSituations());
	}

	private void renderTable17_1() {
		List<XSLFTable> tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(16));
		appendRow(tables.get(0), 10, 5, data.getFamilySeriousDiseaseInsuranceNeeds());
	}

	private void renderTable18_1() {
		List<XSLFTable> tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(17));
		appendRow(tables.get(0), 10, 2, data.getAssetAdjustmentSuggestions());
		XSLFTableRow row = tables.get(0).addRow();
		createCell(row.addCell(), 10, "合计", 2);
		createCell(row.addCell(), 10, "", 2);
		createCell(row.addCell(), 10, "", 2);
		createCell(row.addCell(), 10, "", 2);
		createCell(row.addCell(), 10, String.valueOf(data.getAssetAdjustmentTotalAmount()), 2);
		createCell(row.addCell(), 10, "", 2);
		row.mergeCells(0, 3);
	}

	private void renderTable18_2() {
		List<XSLFTable> tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(17));
		appendRow(tables.get(1), 10, 2, data.getAnnualBalancePlanning());
	}

	private void renderTable19_20() {
		List<XSLFTable> tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(18));
		List<List<String>> values = data.getInvestmentPlanning1();
		if (values != null && values.size() > 0) {
			appendRow(tables.get(0), 8, 0, values.subList(0, Math.min(values.size(), 30)));
			if (values.size() > 30) {
				tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(19));
				appendRow(tables.get(0), 8, 0, values.subList(30, values.size()));
			}
		}
	}

	private void renderTable21_22() {
		List<XSLFTable> tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(20));
		List<List<String>> values = data.getInvestmentPlanning2();
		if (values != null && values.size() > 0) {
			appendRow(tables.get(0), 8, 0, values.subList(0, Math.min(values.size(), 30)));
			if (values.size() > 30) {
				tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(21));
				appendRow(tables.get(0), 8, 0, values.subList(30, values.size()));
			}
		}
	}

	private void renderTable24() {
		List<XSLFTable> tables = pptUtil.getAllTableFromSlide(pptUtil.getSlides().get(23));
		Map<String, List<Double>> values = data.getAssetAllocationChangesBeforeAndAfter();
		if (values != null && values.size() > 0) {
			appendRow(tables.get(0), 10, 10, values.entrySet().stream().map(x -> {
				List<String> vals = new ArrayList<>();
				vals.add(x.getKey());
				vals.addAll(x.getValue().stream().map(String::valueOf).collect(Collectors.toList()));
				return vals;
			}).collect(Collectors.toList()));
		}
	}

	private void renderChart6_1() {
		List<NumVo> datas = new ArrayList<>();
		data.getPropertys().stream()
				.collect(Collectors.groupingBy(NumVo::getCategory, Collectors.summingDouble(NumVo::getValue)))
				.forEach((k, v) -> datas.add(new NumVo(k, v)));
		XSLFChart chart = pptUtil.getChartFromSlide(pptUtil.getSlides().get(5));
		List<List<String>> data = new ArrayList<>();
		List<String> names = new ArrayList<>();
		List<String> values = new ArrayList<>();
		Collections.shuffle(datas);
		datas.forEach(x -> {
			names.add(x.getName());
			values.add(String.valueOf(x.getValue()));
		});
		data.add(names);
		data.add(values);
		pptUtil.updatePieCat(pptUtil.getPieChartFromChart(chart).get(0), 0, data);
		pptUtil.updatePieDataCache(pptUtil.getPieChartFromChart(chart).get(0), 0, values);
	}

	private void renderChart7_1() {
		List<NumVo> datas = new ArrayList<>();
		data.getIncomes().stream()
				.collect(Collectors.groupingBy(NumVo::getCategory, Collectors.summingDouble(NumVo::getValue)))
				.forEach((k, v) -> datas.add(new NumVo(k, v)));
		List<XSLFChart> charts = pptUtil.getAllChartFromSlide(pptUtil.getSlides().get(6));
		List<List<String>> data = new ArrayList<>();
		List<String> names = new ArrayList<>();
		List<String> values = new ArrayList<>();
		Collections.shuffle(datas);
		datas.forEach(x -> {
			names.add(x.getName());
			values.add(String.valueOf(x.getValue()));
		});
		data.add(names);
		data.add(values);
		pptUtil.updatePieCat(pptUtil.getPieChartFromChart(charts.get(0)).get(0), 0, data);
		pptUtil.updatePieDataCache(pptUtil.getPieChartFromChart(charts.get(0)).get(0), 0, values);
	}

	private void renderChart7_2() {
		List<NumVo> datas = new ArrayList<>();
		data.getDebts().stream()
				.collect(Collectors.groupingBy(NumVo::getName, Collectors.summingDouble(NumVo::getValue)))
				.forEach((k, v) -> datas.add(new NumVo(k, v)));
		List<XSLFChart> charts = pptUtil.getAllChartFromSlide(pptUtil.getSlides().get(6));
		List<List<String>> data = new ArrayList<>();
		List<String> names = new ArrayList<>();
		List<String> values = new ArrayList<>();
		Collections.shuffle(datas);
		datas.forEach(x -> {
			names.add(x.getName());
			values.add(String.valueOf(x.getValue()));
		});
		data.add(names);
		data.add(values);
		pptUtil.updatePieCat(pptUtil.getPieChartFromChart(charts.get(1)).get(0), 0, data);
		pptUtil.updatePieDataCache(pptUtil.getPieChartFromChart(charts.get(1)).get(0), 0, values);
	}

	private void renderChart8_1() {
		List<List<String>> datas = new ArrayList<>();
		List<String> columns = new ArrayList<>();
		List<String> standardValues = new ArrayList<>();
		List<String> values = new ArrayList<>();
		columns.add("流动性");
		columns.add("防御性");
		columns.add("收益性");
		standardValues.add("100");
		standardValues.add("100");
		standardValues.add("100");
		data.getAssetLayout().forEach(x -> values.add(String.valueOf(x)));
		datas.add(columns);
		datas.add(values);
		XSLFChart chart = pptUtil.getChartFromSlide(pptUtil.getSlides().get(7));
		pptUtil.updateRadarCat(pptUtil.getRadarChartFromChart(chart).get(0), 0, datas);
		pptUtil.updateRadarDataCache(pptUtil.getRadarChartFromChart(chart).get(0), 0, standardValues);
		pptUtil.updateRadarCat(pptUtil.getRadarChartFromChart(chart).get(0), 1, datas);
		pptUtil.updateRadarDataCache(pptUtil.getRadarChartFromChart(chart).get(0), 1, values);
	}

	private void renderChart9_1() {
		if (data.getLiquidityRatioAmount() != null && data.getLiquidityRatioAmount().size() >= 2) {
			List<NumVo> datas = Arrays.asList(new NumVo("流动性资金", data.getLiquidityRatioAmount().get(0)),
					new NumVo("家庭月支出", data.getLiquidityRatioAmount().get(1)));
			List<XSLFChart> charts = pptUtil.getAllChartFromSlide(pptUtil.getSlides().get(8));
			List<List<String>> data = new ArrayList<>();
			List<String> names = new ArrayList<>();
			List<String> values = new ArrayList<>();
			Collections.shuffle(datas);
			datas.forEach(x -> {
				names.add(x.getName());
				values.add(String.valueOf(x.getValue()));
			});
			data.add(names);
			data.add(values);
			pptUtil.updateBarCat(pptUtil.getBarChartFromChart(charts.get(0)).get(0), 0, data);
			pptUtil.updateBarDataCache(pptUtil.getBarChartFromChart(charts.get(0)).get(0), 0, values);
		}
	}

	private void renderChart9_2() {
		if (data.getDebtRatioAmount() != null && data.getDebtRatioAmount().size() >= 2) {
			List<NumVo> datas = Arrays.asList(new NumVo("净资产总额", data.getDebtRatioAmount().get(0)),
					new NumVo("负债总额", data.getDebtRatioAmount().get(1)));
			List<XSLFChart> charts = pptUtil.getAllChartFromSlide(pptUtil.getSlides().get(8));
			List<List<String>> data = new ArrayList<>();
			List<String> names = new ArrayList<>();
			List<String> values = new ArrayList<>();
			Collections.shuffle(datas);
			datas.forEach(x -> {
				names.add(x.getName());
				values.add(String.valueOf(x.getValue()));
			});
			data.add(names);
			data.add(values);
			pptUtil.updateDoughnutChart(pptUtil.getDoughnutChart(charts.get(1)).get(0), 0, data);
			pptUtil.updateDoughnutDataChart(pptUtil.getDoughnutChart(charts.get(1)).get(0), 0, values);
		}
	}

	private void renderChart10_1() {
		if (data.getBalanceRatioAmount() != null && data.getBalanceRatioAmount().size() >= 2) {
			List<NumVo> datas = Arrays.asList(new NumVo("年结余", data.getBalanceRatioAmount().get(0)),
					new NumVo("年支出", data.getBalanceRatioAmount().get(1)));
			List<XSLFChart> charts = pptUtil.getAllChartFromSlide(pptUtil.getSlides().get(9));
			List<List<String>> data = new ArrayList<>();
			List<String> names = new ArrayList<>();
			List<String> values = new ArrayList<>();
			Collections.shuffle(datas);
			datas.forEach(x -> {
				names.add(x.getName());
				values.add(String.valueOf(x.getValue()));
			});
			data.add(names);
			data.add(values);
			pptUtil.updateBarCat(pptUtil.getBarChartFromChart(charts.get(0)).get(0), 0, data);
			pptUtil.updateBarDataCache(pptUtil.getBarChartFromChart(charts.get(0)).get(0), 0,
					singletonList(values.get(0)));
			pptUtil.updateBarCat(pptUtil.getBarChartFromChart(charts.get(0)).get(0), 1, data);
			pptUtil.updateBarDataCache(pptUtil.getBarChartFromChart(charts.get(0)).get(0), 1,
					singletonList((values.get(1))));
		}
	}

	private void renderChart10_2() {
		if (data.getInvestmentRatioAmount() != null && data.getInvestmentRatioAmount().size() >= 2) {
			List<NumVo> datas = Arrays.asList(new NumVo("非投资资产", data.getInvestmentRatioAmount().get(0)),
					new NumVo("投资资产", data.getInvestmentRatioAmount().get(1)));
			List<XSLFChart> charts = pptUtil.getAllChartFromSlide(pptUtil.getSlides().get(9));
			List<List<String>> data = new ArrayList<>();
			List<String> names = new ArrayList<>();
			List<String> values = new ArrayList<>();
			Collections.shuffle(datas);
			datas.forEach(x -> {
				names.add(x.getName());
				values.add(String.valueOf(x.getValue()));
			});
			data.add(names);
			data.add(values);
			pptUtil.updateDoughnutChart(pptUtil.getDoughnutChart(charts.get(1)).get(0), 0, data);
			pptUtil.updateDoughnutDataChart(pptUtil.getDoughnutChart(charts.get(1)).get(0), 0, values);
		}
	}

	private void renderChart11_1() {
		if (data.getDebtToIncomeRatioAmount() != null && data.getDebtToIncomeRatioAmount().size() >= 2) {
			List<NumVo> datas = Arrays.asList(new NumVo("当年贷款支出", data.getDebtToIncomeRatioAmount().get(0)),
					new NumVo("其他支出+结余", data.getDebtToIncomeRatioAmount().get(1)));
			List<XSLFChart> charts = pptUtil.getAllChartFromSlide(pptUtil.getSlides().get(10));
			List<List<String>> data = new ArrayList<>();
			List<String> names = new ArrayList<>();
			List<String> values = new ArrayList<>();
			Collections.shuffle(datas);
			datas.forEach(x -> {
				names.add(x.getName());
				values.add(String.valueOf(x.getValue()));
			});
			data.add(names);
			data.add(values);
			pptUtil.updateDoughnutChart(pptUtil.getDoughnutChart(charts.get(0)).get(0), 0, data);
			pptUtil.updateDoughnutDataChart(pptUtil.getDoughnutChart(charts.get(0)).get(0), 0, values);
		}
	}

	private void renderChart11_2() {
		if (data.getPassiveIncomeRatioAmount() != null && data.getPassiveIncomeRatioAmount().size() >= 2) {
			List<NumVo> datas = Arrays.asList(new NumVo("被动收入覆盖支出", data.getPassiveIncomeRatioAmount().get(0)),
					new NumVo("工作收入覆盖支出", data.getPassiveIncomeRatioAmount().get(1)));
			List<XSLFChart> charts = pptUtil.getAllChartFromSlide(pptUtil.getSlides().get(10));
			List<List<String>> data = new ArrayList<>();
			List<String> names = new ArrayList<>();
			List<String> values = new ArrayList<>();
			Collections.shuffle(datas);
			datas.forEach(x -> {
				names.add(x.getName());
				values.add(String.valueOf(x.getValue()));
			});
			data.add(names);
			data.add(values);
			pptUtil.updateDoughnutChart(pptUtil.getDoughnutChart(charts.get(1)).get(0), 0, data);
			pptUtil.updateDoughnutDataChart(pptUtil.getDoughnutChart(charts.get(1)).get(0), 0, values);
		}
	}

	private void renderChart24_1() {
		Map<String, List<Double>> values = data.getAssetAllocationChangesBeforeAndAfter();
		if(values != null && values.size() > 0) {
			List<XSLFChart> charts = pptUtil.getAllChartFromSlide(pptUtil.getSlides().get(23));
			int i = 0;
			List<List<String>> data = new ArrayList<>();
			data.add(new ArrayList<>(values.keySet()));
			for (List<Double> vals : values.values()) {
				pptUtil.updateBarCat(pptUtil.getBarChartFromChart(charts.get(0)).get(0), i, data);
				pptUtil.updateBarDataCache(pptUtil.getBarChartFromChart(charts.get(0)).get(0), i,
						vals.stream().map(String::valueOf).collect(Collectors.toList()));
				i++;
			}
		}
	}


	private void appendRow(XSLFTable table, int size, int margin, List<List<String>> values) {
		if (values != null) {
			values.forEach(x -> {
				XSLFTableRow row = table.addRow();
				x.forEach(y -> createCell(row.addCell(), size, y, margin));
			});
		}
	}

	private void createBoldCell(XSLFTableCell cell, int size, String text, int margin) {
		createCell(cell, size, text, margin, true);
	}

	private void createCell(XSLFTableCell cell, int size, String text, int margin) {
		createCell(cell, size, text, margin, false);
	}

	private void createCell(XSLFTableCell cell, int size, String text, int margin, boolean bold) {
		XSLFTextParagraph textParagraph = pptUtil.addCellParagraph(cell);
		textParagraph.setFontAlign(TextParagraph.FontAlign.CENTER);
		pptUtil.addParagraphText(textParagraph, true, text);
		pptUtil.setCellFontfamily(cell, "微软雅黑");    // 字体
		pptUtil.setCellFontSize(cell, String.valueOf(size));  // 字体大小
		pptUtil.setCellHorizontalAlign(cell, "center"); // 单元格水平对齐方式
		pptUtil.setCellVerticalAlign(cell, "center");    // 单元格垂直对齐方式
		pptUtil.setCellColor(cell, "#000000");
		pptUtil.setCellFillColor(cell, "#ffffff");    // 单元格填充颜色
		if (bold) {
			pptUtil.setCellBold(cell, true);
		}
		if (margin > 0) {
			cell.setTopInset(margin);
			cell.setBottomInset(margin);
		}
		cell.setBorderWidth(TableCell.BorderEdge.top, 1);
		cell.setBorderWidth(TableCell.BorderEdge.right, 1);
		cell.setBorderWidth(TableCell.BorderEdge.left, 1);
		cell.setBorderWidth(TableCell.BorderEdge.bottom, 1);
		cell.setBorderColor(TableCell.BorderEdge.top, Color.BLACK);
		cell.setBorderColor(TableCell.BorderEdge.right, Color.BLACK);
		cell.setBorderColor(TableCell.BorderEdge.left, Color.BLACK);
		cell.setBorderColor(TableCell.BorderEdge.bottom, Color.BLACK);
	}

	private Map<String, Object> newMaps(String key, String value) {
		Map<String, Object> paramMap = new HashMap<>(1);
		paramMap.put(key, value);
		return paramMap;
	}

	private String fmt(double d) {
		return NumberFormat.getNumberInstance().format(d);
	}
}